package com.boarsoft.sofa.config;

import java.util.List;
import java.util.Map;
import java.util.Vector;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.alipay.sofa.rpc.client.ProviderGroup;
import com.alipay.sofa.rpc.client.ProviderInfo;
import com.alipay.sofa.rpc.client.ProviderStatus;
import com.alipay.sofa.rpc.config.ConsumerConfig;
import com.alipay.sofa.rpc.listener.ProviderInfoListener;
import com.boarsoft.rpc.bean.RpcRegistry;
import com.boarsoft.rpc.bean.RpcStub;
import com.boarsoft.rpc.core.RpcContext;

public class RpcProviderInfoListener implements ProviderInfoListener {
	private static final Logger log = LoggerFactory.getLogger(RpcProviderInfoListener.class);

	@Autowired
	protected RpcContext rpcContext;
	
	protected ConsumerConfig<?> consumerConfig;
	
	public RpcProviderInfoListener() {}
	
	public RpcProviderInfoListener(RpcContext rpcContext, ConsumerConfig<?> cc) {
		this.rpcContext = rpcContext;
		this.consumerConfig = cc;
	}

	@Override
	public void addProvider(ProviderGroup pg) {
		List<ProviderInfo> lt = pg.getProviderInfos();
		for (ProviderInfo a : lt) {
			String addr = new StringBuilder(a.getHost())//
					.append(":").append(a.getPort()).toString();
			String sk = a.getAttr("sign");
			log.debug("Receive service provider: {} -> {}", addr, sk);
			if (a.getStatus() == ProviderStatus.AVAILABLE) {
				rpcContext.putProvider(new RpcRegistry(addr), //
						sk.concat("/").concat(pg.getName()));
				Map<String, String> saMap = a.getStaticAttrs();
				for (String k : saMap.keySet()) {
					log.debug("get static attr {}={}", k, saMap.get(k));
					String v = saMap.get(k);
					if (v.startsWith("relativeId:") && !"null".equals(v.substring(11))) {
						RpcStub ref = this.rpcContext.getStub(addr);
						int rid = Integer.valueOf(v.substring(11));
						// 发起调用时，rpcContext.newInvoking方法会取此值
						ref.putMethodId(k, rid);
					}
				}
				// if (locksMap.containsKey(sk)) {
				// locksMap.get(sk).countDown(); // 通知调用继续
				// }
			} else {
				rpcContext.removeProvider(addr);
				rpcContext.removeStub(addr);
			}
		}
	}

	@Override
	public void removeProvider(ProviderGroup pg) {
		List<ProviderInfo> lt = pg.getProviderInfos();
		for (ProviderInfo a : lt) {
			String sk = a.getAttr("sign");
			Map<String, Vector<RpcRegistry>> rm = rpcContext.getProviderMap();
			for (String api : rm.keySet()) {
				if (api.contains(sk)) {
					rm.remove(api);
				}
			}
		}
	}

	@Override
	public void updateProviders(ProviderGroup pg) {
		this.removeProvider(pg);
		this.addProvider(pg);
	}

	@Override
	public void updateAllProviders(List<ProviderGroup> pgs) {
		if (pgs == null) {
			return;
		}
		for (ProviderGroup g : pgs) {
			this.updateProviders(g);
		}
	}

}
